# Ce să faci când primești o eroare[[ce-sa-fac-cand-primesti-o-eroare]]

<CourseFloatingBanner chapter={8}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/notebooks/blob/master/course/en/chapter8/section2.ipynb"},
    {label: "Aws Studio", value: "https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/master/course/en/chapter8/section2.ipynb"},
]} />

În această secțiune vom examina câteva erori comune care pot apărea când încercați să generați predicții din modelul Transformer pe care l-ați ajustat recent. Aceasta vă va pregăti pentru [secțiunea 4](/course/chapter8/section4), unde vom explora cum să depanați faza de antrenament în sine.

<Youtube id="DQ-CpJn6Rc4"/>

Am pregătit un [repository model șablon](https://huggingface.co/lewtun/distilbert-base-uncased-finetuned-squad-d5716d28) pentru această secțiune, și dacă doriți să rulați codul din acest capitol trebuie mai întâi să copiați modelul în contul dumneavoastră pe [Hugging Face Hub](https://huggingface.co). Pentru a face acest lucru, mai întâi conectați-vă rulând fie următoarele într-un notebook Jupyter:

```python
from huggingface_hub import notebook_login

notebook_login()
```

sau următoarele în terminalul dumneavoastră preferat:

```bash
huggingface-cli login
```

Aceasta vă va solicita să introduceți numele de utilizator și parola și va salva un token sub *~/.cache/huggingface/*. Odată ce v-ați conectat, puteți copia repository-ul șablon cu următoarea funcție:

```python
from distutils.dir_util import copy_tree
from huggingface_hub import Repository, snapshot_download, create_repo, get_full_repo_name


def copy_repository_template():
    # Clone the repo and extract the local path
    template_repo_id = "lewtun/distilbert-base-uncased-finetuned-squad-d5716d28"
    commit_hash = "be3eaffc28669d7932492681cd5f3e8905e358b4"
    template_repo_dir = snapshot_download(template_repo_id, revision=commit_hash)
    # Create an empty repo on the Hub
    model_name = template_repo_id.split("/")[1]
    create_repo(model_name, exist_ok=True)
    # Clone the empty repo
    new_repo_id = get_full_repo_name(model_name)
    new_repo_dir = model_name
    repo = Repository(local_dir=new_repo_dir, clone_from=new_repo_id)
    # Copy files
    copy_tree(template_repo_dir, new_repo_dir)
    # Push to Hub
    repo.push_to_hub()
```

Acum când apelați `copy_repository_template()`, aceasta va crea o copie a repository-ului șablon sub contul dumneavoastră.

## Depanarea pipeline-ului din 🤗 Transformers[[depanarea-pipeline-ului-din-transformers]]

Pentru a începe călătoria noastră în lumea minunată a depanării modelelor Transformer, considerați următorul scenariu: lucrați cu un coleg la un proiect de răspuns la întrebări pentru a ajuta clienții unui site web de e-commerce să găsească răspunsuri despre produsele de consum. Colegul dumneavoastră vă trimite un mesaj precum:

> Salut! Tocmai am rulat un experiment folosind tehnicile din [Capitolul 7](/course/chapter7/7) al cursului Hugging Face și am obținut rezultate grozave pe SQuAD! Cred că putem folosi acest model ca punct de plecare pentru proiectul nostru. ID-ul modelului pe Hub este "lewtun/distillbert-base-uncased-finetuned-squad-d5716d28". Simte-te liber să îl testezi :)

Iar primul lucru la care vă gândiți este să încărcați modelul folosind `pipeline` din 🤗 Transformers:

```python
from transformers import pipeline

model_checkpoint = get_full_repo_name("distillbert-base-uncased-finetuned-squad-d5716d28")
reader = pipeline("question-answering", model=model_checkpoint)
```

```python out
"""
OSError: Can't load config for 'lewtun/distillbert-base-uncased-finetuned-squad-d5716d28'. Make sure that:

- 'lewtun/distillbert-base-uncased-finetuned-squad-d5716d28' is a correct model identifier listed on 'https://huggingface.co/models'

- or 'lewtun/distillbert-base-uncased-finetuned-squad-d5716d28' is the correct path to a directory containing a config.json file
"""
```

Oh nu, se pare că ceva a mers prost! Dacă sunteți nou în programare, acest tip de erori pot părea puțin criptice la început (ce este un `OSError`?!). Eroarea afișată aici este doar ultima parte dintr-un raport de eroare mult mai mare numit _Python traceback_ (cunoscut și ca stack trace). De exemplu, dacă rulați acest cod pe Google Colab, ar trebui să vedeți ceva similar cu următoarea captură de ecran:

<div class="flex justify-center">
<img src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter8/traceback.png" alt="Un traceback Python." width="100%"/>
</div>

Există multe informații conținute în aceste rapoarte, așa că să parcurgem împreună părțile cheie. Primul lucru de reținut este că traceback-urile ar trebui citite _de jos în sus_. Aceasta poate părea ciudat dacă sunteți obișnuiți să citiți textul în engleză de sus în jos, dar reflectă faptul că traceback-ul arată secvența de apeluri de funcții pe care `pipeline` le face când descarcă modelul și tokenizer-ul. (Consultați [Capitolul 2](/course/chapter2) pentru mai multe detalii despre cum funcționează `pipeline` în culise.)

> [!TIP]
> 🚨 Vedeți acea casetă albastră din jurul "6 frames" în traceback-ul din Google Colab? Aceasta este o caracteristică specială a Colab, care comprimă traceback-ul în "frame-uri". Dacă nu reușiți să găsiți sursa unei erori, asigurați-vă că extindeți traceback-ul complet făcând clic pe acele două săgeți mici.

Aceasta înseamnă că ultima linie a traceback-ului indică ultimul mesaj de eroare și dă numele excepției care a fost ridicată. În acest caz, tipul excepției este `OSError`, care indică o eroare legată de sistem. Dacă citim mesajul de eroare însoțitor, putem vedea că pare să existe o problemă cu fișierul *config.json* al modelului și ni se dau două sugestii pentru a o rezolva:

```python out
"""
Make sure that:

- 'lewtun/distillbert-base-uncased-finetuned-squad-d5716d28' is a correct model identifier listed on 'https://huggingface.co/models'

- or 'lewtun/distillbert-base-uncased-finetuned-squad-d5716d28' is the correct path to a directory containing a config.json file
"""
```

> [!TIP]
> 💡 Dacă întâlniți un mesaj de eroare care este dificil de înțeles, doar copiați și lipiți mesajul în bara de căutare Google sau [Stack Overflow](https://stackoverflow.com/) (da, chiar!). Există o șansă bună că nu sunteți prima persoană care întâlnește eroarea, și aceasta este o modalitate bună de a găsi soluții pe care alții din comunitate le-au postat. De exemplu, căutarea pentru `OSError: Can't load config for` pe Stack Overflow dă mai multe [rezultate](https://stackoverflow.com/search?q=OSError%3A+Can%27t+load+config+for+) care ar putea fi folosite ca punct de plecare pentru rezolvarea problemei.

Prima sugestie ne cere să verificăm dacă ID-ul modelului este într-adevăr corect, așa că primul lucru de făcut este să copiem identificatorul și să îl lipim în bara de căutare a Hub-ului:

<div class="flex justify-center">
<img src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter8/wrong-model-id.png" alt="Numele greșit al modelului." width="100%"/>
</div>

Hmm, într-adevăr pare că modelul colegului nostru nu este pe Hub... aha, dar există o greșeală de tipar în numele modelului! DistilBERT are doar un "l" în numele său, așa că să corectăm asta și să căutăm "lewtun/distilbert-base-uncased-finetuned-squad-d5716d28" în schimb:

<div class="flex justify-center">
<img src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter8/true-model-id.png" alt="Numele corect al modelului." width="100%"/>
</div>

Bun, aceasta a dat un rezultat. Acum să încercăm să descărcăm din nou modelul cu ID-ul corect:

```python
model_checkpoint = get_full_repo_name("distilbert-base-uncased-finetuned-squad-d5716d28")
reader = pipeline("question-answering", model=model_checkpoint)
```

```python out
"""
OSError: Can't load config for 'lewtun/distilbert-base-uncased-finetuned-squad-d5716d28'. Make sure that:

- 'lewtun/distilbert-base-uncased-finetuned-squad-d5716d28' is a correct model identifier listed on 'https://huggingface.co/models'

- or 'lewtun/distilbert-base-uncased-finetuned-squad-d5716d28' is the correct path to a directory containing a config.json file
"""
```

Argh, eșuat din nou -- bun venit în viața de zi cu zi a unui inginer de machine learning! Deoarece am corectat ID-ul modelului, problema trebuie să fie în repository în sine. O modalitate rapidă de a accesa conținutul unui repository pe 🤗 Hub este prin funcția `list_repo_files()` din biblioteca `huggingface_hub`:

```python
from huggingface_hub import list_repo_files

list_repo_files(repo_id=model_checkpoint)
```

```python out
['.gitattributes', 'README.md', 'pytorch_model.bin', 'special_tokens_map.json', 'tokenizer_config.json', 'training_args.bin', 'vocab.txt']
```

Interesant -- nu pare să existe un fișier *config.json* în repository! Nu e de mirare că `pipeline`-ul nostru nu a putut încărca modelul; colegul nostru trebuie să fi uitat să împingă acest fișier pe Hub după ce l-a ajustat fin. În acest caz, problema pare destul de simplă de rezolvat: am putea să îi cerem să adauge fișierul, sau, deoarece putem vedea din ID-ul modelului că modelul preantrenat folosit a fost [`distilbert-base-uncased`](https://huggingface.co/distilbert-base-uncased), putem descărca configurația pentru acest model și să o împingem în repository-ul nostru pentru a vedea dacă aceasta rezolvă problema. Să încercăm asta. Folosind tehnicile pe care le-am învățat în [Capitolul 2](/course/chapter2), putem descărca configurația modelului cu clasa `AutoConfig`:

```python
from transformers import AutoConfig

pretrained_checkpoint = "distilbert-base-uncased"
config = AutoConfig.from_pretrained(pretrained_checkpoint)
```

> [!WARNING]
> 🚨 Abordarea pe care o adoptăm aici nu este infailibilă, deoarece colegul nostru poate să fi modificat configurația `distilbert-base-uncased` înainte de a ajusta fin modelul. În viața reală, am vrea să verificăm cu ei mai întâi, dar în scopurile acestei secțiuni vom presupune că au folosit configurația implicită.

Apoi putem împinge aceasta în repository-ul nostru de model cu funcția `push_to_hub()` a configurației:

```python
config.push_to_hub(model_checkpoint, commit_message="Add config.json")
```

Acum putem testa dacă aceasta a funcționat încărcând modelul din cel mai recent commit pe ramura `main`:

```python
reader = pipeline("question-answering", model=model_checkpoint, revision="main")

context = r"""
Extractive Question Answering is the task of extracting an answer from a text
given a question. An example of a question answering dataset is the SQuAD
dataset, which is entirely based on that task. If you would like to fine-tune a
model on a SQuAD task, you may leverage the
examples/pytorch/question-answering/run_squad.py script.

🤗 Transformers is interoperable with the PyTorch, TensorFlow, and JAX
frameworks, so you can use your favourite tools for a wide variety of tasks!
"""

question = "What is extractive question answering?"
reader(question=question, context=context)
```

```python out
{'score': 0.38669535517692566,
 'start': 34,
 'end': 95,
 'answer': 'the task of extracting an answer from a text given a question'}
```

Woohoo, a funcționat! Să recapitulăm ce ați învățat tocmai:

- Mesajele de eroare în Python sunt cunoscute ca _traceback-uri_ și sunt citite de jos în sus. Ultima linie a mesajului de eroare conține de obicei informațiile de care aveți nevoie pentru a localiza sursa problemei.
- Dacă ultima linie nu conține informații suficiente, parcurgeți traceback-ul în sus și vedeți dacă puteți identifica unde în codul sursă apare eroarea.
- Dacă niciunul dintre mesajele de eroare nu vă poate ajuta să depanați problema, încercați să căutați online o soluție la o problemă similară.
- Biblioteca `huggingface_hub` oferă o suită de instrumente pe care le puteți folosi pentru a interacționa cu și a depana repository-urile de pe Hub.

Acum că știți cum să depanați un pipeline, să aruncăm o privire la un exemplu mai complicat în forward pass-ul modelului în sine.

## Depanarea forward pass-ului modelului dumneavoastră[[depanarea-forward-pass-ului-modelului-dumneavoastra]]

Deși `pipeline` este grozav pentru majoritatea aplicațiilor unde aveți nevoie să generați rapid predicții, uneori va trebui să accesați logit-urile modelului (să zicem, dacă aveți o post-procesare personalizată pe care ați dori să o aplicați). Pentru a vedea ce poate merge prost în acest caz, să extragem mai întâi modelul și tokenizer-ul din `pipeline`-ul nostru:

```python
tokenizer = reader.tokenizer
model = reader.model
```

Apoi avem nevoie de o întrebare, așa că să vedem dacă framework-urile noastre preferate sunt suportate:

```python
question = "Which frameworks can I use?"
```

Așa cum am văzut în [Capitolul 7](/course/chapter7), pașii obișnuiți pe care trebuie să îi facem sunt tokenizarea intrărilor, extragerea logit-urilor token-urilor de început și sfârșit, și apoi decodarea span-ului de răspuns:

```python
import torch

inputs = tokenizer(question, context, add_special_tokens=True)
input_ids = inputs["input_ids"][0]
outputs = model(**inputs)
answer_start_scores = outputs.start_logits
answer_end_scores = outputs.end_logits
# Get the most likely beginning of answer with the argmax of the score
answer_start = torch.argmax(answer_start_scores)
# Get the most likely end of answer with the argmax of the score
answer_end = torch.argmax(answer_end_scores) + 1
answer = tokenizer.convert_tokens_to_string(
    tokenizer.convert_ids_to_tokens(input_ids[answer_start:answer_end])
)
print(f"Question: {question}")
print(f"Answer: {answer}")
```

```python out
"""
OSError: Can't load config for 'lewtun/distillbert-base-uncased-finetuned-squad-d5716d28'. Make sure that:

- 'lewtun/distillbert-base-uncased-finetuned-squad-d5716d28' is a correct model identifier listed on 'https://huggingface.co/models'

- or 'lewtun/distillbert-base-uncased-finetuned-squad-d5716d28' is the correct path to a directory containing a config.json file
"""
```

Oh nu, se pare că avem o eroare în codul nostru! Dar nu ne temem de puțină depanare. Puteți folosi debugger-ul Python într-un notebook:

<Youtube id="rSPyvPw0p9k"/>

sau într-un terminal:

<Youtube id="5PkZ4rbHL6c"/>

Aici, citirea mesajului de eroare ne spune că `'list' object has no attribute 'size'`, și putem vedea o săgeată `-->` care indică linia unde a fost ridicată problema în `model(**inputs)`. Puteți depana aceasta interactiv folosind debugger-ul Python, dar pentru moment vom afișa pur și simplu o porțiune din `inputs` pentru a vedea ce avem:

```python
inputs["input_ids"][:5]
```

```python out
[101, 2029, 7705, 2015, 2064]
```

Aceasta cu siguranță arată ca o `list` Python obișnuită, dar să verificăm din nou tipul:

```python
type(inputs["input_ids"])
```

```python out
list
```

Da, aceasta este cu siguranță o `list` Python. Deci ce a mers prost? Amintiți-vă din [Capitolul 2](/course/chapter2) că clasele `AutoModelForXxx` din 🤗 Transformers operează pe _tensori_ (fie în PyTorch sau TensorFlow), și o operație comună este să extragi dimensiunile unui tensor folosind `Tensor.size()` în, să zicem, PyTorch. Să aruncăm din nou o privire la traceback, pentru a vedea care linie a declanșat excepția:

```
~/miniconda3/envs/huggingface/lib/python3.8/site-packages/transformers/models/distilbert/modeling_distilbert.py in forward(self, input_ids, attention_mask, head_mask, inputs_embeds, output_attentions, output_hidden_states, return_dict)
    471             raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")
    472         elif input_ids is not None:
--> 473             input_shape = input_ids.size()
    474         elif inputs_embeds is not None:
    475             input_shape = inputs_embeds.size()[:-1]

AttributeError: 'list' object has no attribute 'size'
```

Se pare că codul nostru a încercat să apeleze `input_ids.size()`, dar aceasta în mod clar nu va funcționa pentru o `list` Python, care este doar un container. Cum putem rezolva această problemă? Căutarea mesajului de eroare pe Stack Overflow oferă destul de multe [rezultate](https://stackoverflow.com/search?q=AttributeError%3A+%27list%27+object+has+no+attribute+%27size%27&s=c15ec54c-63cb-481d-a749-408920073e8f) relevante. Făcând clic pe primul afișează o întrebare similară cu a noastră, cu răspunsul arătat în captura de ecran de mai jos:

<div class="flex justify-center">
<img src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter8/stack-overflow.png" alt="Un răspuns de pe Stack Overflow." width="100%"/>
</div>

Răspunsul recomandă să adăugăm `return_tensors='pt'` la tokenizer, așa că să vedem dacă aceasta funcționează pentru noi:

```python out
inputs = tokenizer(question, context, add_special_tokens=True, return_tensors="pt")
input_ids = inputs["input_ids"][0]
outputs = model(**inputs)
answer_start_scores = outputs.start_logits
answer_end_scores = outputs.end_logits
# Get the most likely beginning of answer with the argmax of the score
answer_start = torch.argmax(answer_start_scores)
# Get the most likely end of answer with the argmax of the score
answer_end = torch.argmax(answer_end_scores) + 1
answer = tokenizer.convert_tokens_to_string(
    tokenizer.convert_ids_to_tokens(input_ids[answer_start:answer_end])
)
print(f"Question: {question}")
print(f"Answer: {answer}")
```

```python out
"""
Question: Which frameworks can I use?
Answer: pytorch, tensorflow, and jax
"""
```

Minunat, a funcționat! Acesta este un exemplu grozav de cât de util poate fi Stack Overflow: prin identificarea unei probleme similare, am putut beneficia de experiența altora din comunitate. Cu toate acestea, o căutare ca aceasta nu va da întotdeauna un răspuns relevant, așa că ce puteți face în astfel de cazuri? Din fericire, există o comunitate primitoare de dezvoltatori pe [forumurile Hugging Face](https://discuss.huggingface.co/) care vă pot ajuta! În secțiunea următoare, vom arunca o privire asupra modului în care puteți formula întrebări bune pe forum care au șanse să primească răspuns. 